home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / mozilla-firefox / include / xpcom / nsRecyclingAllocator.h < prev    next >
C/C++ Source or Header  |  2006-05-08  |  7KB  |  209 lines

  1. /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is mozilla.org code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Netscape Communications Corporation.
  19.  * Portions created by the Initial Developer are Copyright (C) 2001, 2002
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *    Suresh Duddi <dp@netscape.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. /*
  40.  * nsRecyclingAllocator
  41.  *
  42.  * This allocator is useful when we cycle through a small set of allocations
  43.  * repeatedly with minimal overlap. For eg. something we do for every gif
  44.  * file read (or) buffers required for decompression of every file from jar.
  45.  *
  46.  * What this does is keeps around the first set of memory allocated and
  47.  * reuses it subsequently. If all buckets are full, this falls back to
  48.  * malloc/free
  49.  *
  50.  * Uses a timer to release all memory allocated if not used for more than
  51.  * 10 secs automatically.
  52.  *
  53.  * Also there is a 4 byte maintenance overhead on every allocation.
  54.  *
  55.  * This allocator is thread safe.
  56.  *
  57.  * CAVEATS: As the number of buckets increases, this allocators performance
  58.  *          will drop. As a general guideline, dont use this for more
  59.  *          than NS_MAX_BLOCKS
  60.  */
  61.  
  62. #ifndef nsRecyclingAllocator_h__
  63. #define nsRecyclingAllocator_h__
  64.  
  65. #include "nscore.h"
  66. #include "pratom.h"
  67. #include "prlock.h"
  68. #include "nsIRecyclingAllocator.h"
  69. #include "nsIGenericFactory.h"
  70.  
  71. #define NS_DEFAULT_RECYCLE_TIMEOUT 10  // secs
  72. #define NS_MAX_BLOCKS              24
  73. #define NS_ALLOCATOR_OVERHEAD_BYTES (sizeof(Block)) // bytes
  74.  
  75. class nsITimer;
  76. class nsIMemory;
  77.  
  78. class NS_COM nsRecyclingAllocator {
  79.  protected:
  80.     struct Block {
  81.       PRSize bytes;
  82.     };
  83.  
  84.     // Make |BlockStoreNode| a |friend| so it can access |Block|.
  85.     struct BlockStoreNode;
  86.     friend struct BlockStoreNode;
  87.  
  88.     struct BlockStoreNode {
  89.       BlockStoreNode() : bytes(0), block(nsnull), next(nsnull) {};
  90.       PRSize bytes;
  91.       Block *block;
  92.       BlockStoreNode *next;
  93.     };
  94.  
  95. #define DATA(block) ((void *)(((char *)block) + NS_ALLOCATOR_OVERHEAD_BYTES))
  96. #define DATA_TO_BLOCK(data) ((Block *)((char *)(data) - NS_ALLOCATOR_OVERHEAD_BYTES))
  97.  
  98.     // mMaxBlocks: Maximum number of blocks that can be allocated
  99.     PRUint32 mMaxBlocks;
  100.  
  101.     // mBlocks:
  102.     //  All blocks used or not.
  103.     BlockStoreNode *mBlocks;
  104.  
  105.     // mFreeList
  106.     //  A linked list of free blocks sorted by increasing order of size
  107.     BlockStoreNode* mFreeList;
  108.  
  109.     // mNotUsedList
  110.     //  A linked list of BlockStoreNodes that are not used to store
  111.     //  any block information. When we add blocks into mFreeList, we
  112.     //  take BlockStoreNode from here.
  113.     BlockStoreNode* mNotUsedList;
  114.  
  115.     // mLock: Thread safety of mFreeList and mNotUsedList
  116.     PRLock *mLock;
  117.  
  118.     // Timer for freeing unused memory
  119.     nsITimer *mRecycleTimer;
  120.  
  121.     // mRecycleAfter:
  122.     //  Allocator should be untouched for this many seconds for freeing
  123.     //  unused Blocks.
  124.     PRUint32 mRecycleAfter;
  125.  
  126.     // mTouched:
  127.     //  says if the allocator touched any bucket. If allocator didn't touch
  128.     //  any bucket over a time time interval, timer will call FreeUnusedBuckets()
  129.     PRInt32 mTouched;
  130.  
  131.     // mId:
  132.     //  a string for identifying the user of nsRecyclingAllocator
  133.     //  User mainly for debug prints
  134.     const char *mId;
  135.  
  136. #ifdef DEBUG
  137.     // mNAllocated: Number of blocks allocated
  138.     PRInt32 mNAllocated;
  139. #endif
  140.  
  141.  public:
  142.  
  143.     // nbucket : number of buckets to hold. Capped at NS_MAX_BUCKET
  144.     // recycleAfter : Try recycling allocated buckets after this many seconds
  145.     // id : a string used to identify debug prints. Will not be released.
  146.     nsRecyclingAllocator(PRUint32 nbucket = 0, PRUint32 recycleAfter = NS_DEFAULT_RECYCLE_TIMEOUT,
  147.                          const char *id = NULL);
  148.     ~nsRecyclingAllocator();
  149.  
  150.     nsresult Init(PRUint32 nbucket, PRUint32 recycleAfter, const char *id);
  151.  
  152.     // Allocation and free routines
  153.     void* Malloc(PRSize size, PRBool zeroit = PR_FALSE);
  154.     void  Free(void *ptr);
  155.  
  156.     void* Calloc(PRUint32 items, PRSize size)
  157.     {
  158.         return Malloc(items * size, PR_TRUE);
  159.     }
  160.  
  161.     // FreeUnusedBuckets - Frees any bucket memory that isn't in use
  162.     void FreeUnusedBuckets();
  163.  
  164.  protected:
  165.  
  166.     // Timer callback to trigger unused memory
  167.     static void nsRecycleTimerCallback(nsITimer *aTimer, void *aClosure);
  168.  
  169.     // Freelist management
  170.     // FindFreeBlock: return a free block that can hold bytes (best fit)
  171.     Block* FindFreeBlock(PRSize bytes);
  172.     // AddToFreeList: adds block into our freelist for future retrieval.
  173.     //  Returns PR_TRUE is addition was successful. PR_FALSE otherewise.
  174.     PRBool AddToFreeList(Block* block);
  175.  
  176.     // Touch will mark that someone used this allocator
  177.     // Timer based release will free unused memory only if allocator
  178.     // was not touched for mRecycleAfter seconds.
  179.     void Touch() {
  180.         if (!mTouched)
  181.             PR_AtomicSet(&mTouched, 1);
  182.     }
  183.     void Untouch() {
  184.         PR_AtomicSet(&mTouched, 0);
  185.     }
  186.  
  187.     friend void nsRecycleTimerCallback(nsITimer *aTimer, void *aClosure);
  188. };
  189.  
  190. // ----------------------------------------------------------------------
  191. // Wrapping the recyling allocator with nsIMemory
  192. // ----------------------------------------------------------------------
  193.  
  194. // Wrapping the nsRecyclingAllocator with nsIMemory
  195. class nsRecyclingAllocatorImpl : public nsRecyclingAllocator, public nsIRecyclingAllocator {
  196. public:
  197.     NS_DECL_ISUPPORTS
  198.     NS_DECL_NSIMEMORY
  199.     NS_DECL_NSIRECYCLINGALLOCATOR
  200.  
  201.     nsRecyclingAllocatorImpl()
  202.     {
  203.     }
  204.  
  205. private:
  206.     ~nsRecyclingAllocatorImpl() {}
  207. };
  208. #endif // nsRecyclingAllocator_h__
  209.